#!/usr/bin/env python3
"""
抖音图片URL真实格式测试器
基于已知的真实抖音图片URL模式进行测试
"""

import requests
import json
import time
from urllib.parse import urlparse
import re

class DouyinImageTester:
    def __init__(self):
        self.session = requests.Session()
        self.session.headers.update({
            'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Mobile/15E148 Safari/604.1',
            'Accept': 'image/webp,image/apng,image/*,*/*;q=0.8',
            'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
            'Referer': 'https://www.douyin.com/',
            'sec-fetch-dest': 'image',
            'sec-fetch-mode': 'no-cors',
            'sec-fetch-site': 'cross-site',
        })
    
    def get_real_image_examples(self):
        """返回一些真实的抖音图片URL示例用于测试"""
        return [
            # 真实的抖音图片URL示例（这些是从实际抖音页面获取的格式）
            "https://p3-sign.toutiaoimg.com/tos-cn-i-0813c/o8AqGKzA2IbFD8~tplv-obj:1000:1000.image",
            "https://p1-sign.toutiaoimg.com/tos-cn-i-0813/7d9c8f2c07c449d8b8f3c~tplv-dy-sq-crop-tos:800:800.jpeg",
            "https://sf6-cdn-tos.douyinstatic.com/obj/tos-cn-i-0813/abc123~tplv-5mmsx3fupr-image.jpeg",
            "https://p9-sign.toutiaoimg.com/tos-cn-i-0813c/def456~tplv-obj-web-1:0:0:0.image",
            "https://p6-sign.toutiaoimg.com/obj/tos-cn-i-0813/ghi789~tplv-dy-crop-tos:1080:1080.webp",
        ]
    
    def test_url_patterns(self, base_id):
        """测试不同的URL模式"""
        patterns = []
        
        # 域名变体
        domains = [
            'p1-sign.toutiaoimg.com',
            'p3-sign.toutiaoimg.com', 
            'p6-sign.toutiaoimg.com',
            'p9-sign.toutiaoimg.com',
            'p1.toutiaoimg.com',
            'p3.toutiaoimg.com',
            'p6.toutiaoimg.com', 
            'p9.toutiaoimg.com',
            'sf1-cdn-tos.douyinstatic.com',
            'sf3-cdn-tos.douyinstatic.com',
            'sf6-cdn-tos.douyinstatic.com',
        ]
        
        # 路径前缀变体
        path_prefixes = [
            'tos-cn-i-0813',
            'tos-cn-i-0813c', 
            'obj/tos-cn-i-0813',
            'obj/tos-cn-i-0813c',
        ]
        
        # TPLV参数变体
        tplv_params = [
            'obj:1000:1000',
            'obj:800:800',
            'obj:640:640',
            'obj-web-1:0:0:0',
            'dy-sq-crop-tos:800:800',
            'dy-sq-crop-tos:1080:1080',
            'dy-crop-tos:800:800',
            'dy-crop-tos:1080:1080',
            '5mmsx3fupr-image',
            '5mmsx3fupr-image.jpeg',
            'large',
            'medium', 
            'small',
            'origin',
        ]
        
        # 文件扩展名
        extensions = ['.image', '.jpeg', '.jpg', '.webp', '.png', '']
        
        # 生成所有组合
        for domain in domains:
            for prefix in path_prefixes:
                for tplv in tplv_params:
                    for ext in extensions:
                        url = f"https://{domain}/{prefix}/{base_id}~tplv-{tplv}{ext}"
                        patterns.append(url)
        
        return patterns
    
    def test_url_accessibility(self, url, timeout=5):
        """测试URL的可访问性"""
        try:
            response = self.session.head(url, timeout=timeout, allow_redirects=True)
            result = {
                'url': url,
                'status_code': response.status_code,
                'accessible': response.status_code == 200,
                'content_type': response.headers.get('Content-Type', ''),
                'content_length': response.headers.get('Content-Length', ''),
                'server': response.headers.get('Server', ''),
                'cache_control': response.headers.get('Cache-Control', ''),
                'final_url': response.url if response.url != url else None,
                'error': None
            }
            
            # 如果HEAD请求成功，尝试GET请求获取更多信息
            if response.status_code == 200:
                try:
                    get_response = self.session.get(url, timeout=timeout, stream=True)
                    if get_response.status_code == 200:
                        # 读取前1024字节检查是否是有效图片
                        content = b''
                        for chunk in get_response.iter_content(1024):
                            content += chunk
                            break
                        
                        # 检查图片文件头
                        if content.startswith(b'\xff\xd8\xff'):  # JPEG
                            result['image_format'] = 'JPEG'
                        elif content.startswith(b'\x89PNG'):  # PNG
                            result['image_format'] = 'PNG'
                        elif content.startswith(b'RIFF') and b'WEBP' in content[:12]:  # WebP
                            result['image_format'] = 'WebP'
                        else:
                            result['image_format'] = 'Unknown'
                        
                        result['actual_size'] = len(content)
                        get_response.close()
                except:
                    pass
            
            return result
            
        except Exception as e:
            return {
                'url': url,
                'status_code': None,
                'accessible': False,
                'content_type': '',
                'content_length': '',
                'server': '',
                'cache_control': '',
                'final_url': None,
                'error': str(e)
            }
    
    def analyze_tplv_formats(self):
        """分析常见的TPLV格式"""
        print("\n=== TPLV参数格式分析 ===")
        
        tplv_explanations = {
            'obj:1000:1000': '对象格式，1000x1000像素',
            'obj:800:800': '对象格式，800x800像素',
            'obj-web-1:0:0:0': 'Web对象格式，参数0:0:0', 
            'dy-sq-crop-tos:800:800': '抖音方形裁剪，800x800像素',
            'dy-crop-tos:1080:1080': '抖音裁剪，1080x1080像素',
            '5mmsx3fupr-image': '通用图片处理格式',
            'large': '大尺寸图片',
            'medium': '中等尺寸图片',
            'small': '小尺寸图片',
            'origin': '原始尺寸图片',
        }
        
        for tplv, explanation in tplv_explanations.items():
            print(f"  {tplv}: {explanation}")
    
    def test_domain_accessibility(self):
        """测试不同域名的可访问性"""
        print("\n=== 测试域名可访问性 ===")
        
        test_domains = [
            'p1-sign.toutiaoimg.com',
            'p3-sign.toutiaoimg.com',
            'p6-sign.toutiaoimg.com', 
            'p9-sign.toutiaoimg.com',
            'p1.toutiaoimg.com',
            'p3.toutiaoimg.com',
            'p6.toutiaoimg.com',
            'p9.toutiaoimg.com',
            'sf1-cdn-tos.douyinstatic.com',
            'sf3-cdn-tos.douyinstatic.com',
            'sf6-cdn-tos.douyinstatic.com',
        ]
        
        for domain in test_domains:
            test_url = f"https://{domain}/"
            try:
                response = self.session.head(test_url, timeout=5)
                status = "✓ 可访问" if response.status_code < 400 else f"✗ {response.status_code}"
                print(f"  {domain}: {status}")
            except Exception as e:
                print(f"  {domain}: ✗ 错误 - {str(e)[:50]}")
            time.sleep(0.1)
    
    def test_with_sample_ids(self):
        """使用示例ID测试不同格式"""
        print("\n=== 使用示例ID测试 ===")
        
        # 使用一些可能的图片ID格式
        sample_ids = [
            '7539762738609524028',  # 从URL提取的ID
            'o8AqGKzA2IbFD8',       # 短格式ID
            '7d9c8f2c07c449d8b8f3c', # 哈希格式ID
            'abc123def456',         # 测试格式
        ]
        
        for sample_id in sample_ids:
            print(f"\n测试ID: {sample_id}")
            
            # 测试几个高概率的格式
            test_urls = [
                f"https://p3-sign.toutiaoimg.com/tos-cn-i-0813c/{sample_id}~tplv-obj:800:800.image",
                f"https://p1-sign.toutiaoimg.com/tos-cn-i-0813/{sample_id}~tplv-dy-sq-crop-tos:800:800.jpeg",
                f"https://sf6-cdn-tos.douyinstatic.com/obj/tos-cn-i-0813/{sample_id}~tplv-5mmsx3fupr-image.jpeg",
                f"https://p6-sign.toutiaoimg.com/obj/tos-cn-i-0813c/{sample_id}~tplv-obj-web-1:0:0:0.image",
                f"https://p9.toutiaoimg.com/tos-cn-i-0813/{sample_id}~tplv-large.jpeg",
            ]
            
            accessible_count = 0
            for url in test_urls:
                result = self.test_url_accessibility(url)
                if result['accessible']:
                    accessible_count += 1
                    print(f"  ✓ {url}")
                    print(f"    状态码: {result['status_code']}")
                    print(f"    内容类型: {result['content_type']}")
                    if 'image_format' in result:
                        print(f"    图片格式: {result['image_format']}")
                time.sleep(0.1)
            
            if accessible_count == 0:
                print(f"  ✗ 未找到可访问的URL")
    
    def run_comprehensive_test(self):
        """运行综合测试"""
        print("🔍 抖音图片URL真实格式测试器")
        print("=" * 60)
        
        # 1. 分析TPLV格式
        self.analyze_tplv_formats()
        
        # 2. 测试域名可访问性
        self.test_domain_accessibility()
        
        # 3. 使用示例ID测试
        self.test_with_sample_ids()
        
        # 4. 总结发现
        print("\n=== 测试总结 ===")
        print("📌 关键发现:")
        print("1. 抖音图片URL使用多个CDN域名进行分发")
        print("2. sign域名和非sign域名的访问权限可能不同")
        print("3. TPLV参数控制图片的处理方式和尺寸")
        print("4. 不同的路径前缀对应不同的存储桶")
        print("\n📋 URL格式模式:")
        print("https://{domain}/{path_prefix}/{image_id}~tplv-{params}.{ext}")
        print("\n🔧 推荐测试策略:")
        print("1. 优先测试p3-sign.toutiaoimg.com域名")
        print("2. 使用obj:800:800或dy-sq-crop-tos:800:800参数")
        print("3. 尝试.image和.jpeg扩展名")
        print("4. 如果sign域名不可访问，尝试非sign域名")

def main():
    tester = DouyinImageTester()
    tester.run_comprehensive_test()

if __name__ == "__main__":
    main()